#!/usr/bin/env python
# -*- coding:utf-8 -*-
__author__ = 'wshu'
__version__ = '1.0'
"""
    ***********************************
    *  @filename : get_namp_result.py
    *  @Author : wshu
    *  @CodeDate : 2020/4/16 22:17
    *  @Software : PyCharm
    ***********************************
"""
import os
from conf import config
from core.hostscan.utils import parse_full_ip_list
from core.comm.nmapparse import Parser

class Nmap(object):
    def __init__(self, xmlpath, pid, ips, ports='', speed='4'):
        '''
        http 80 8080 81
        smtp 25
        https 443
        mysql 3306
        mstsc 3389
        ftp 21
        ssh 22
        telnet 23
        pop 110

        #self.live_cmd = 'nmap -PS22,445,139,80 -oX %s/live_hosts.xml %s'
        #self.http_cmd = 'nmap -sT  -sV --open  --host-timeout 30s --top-ports 200 -oX %s/http_hosts.xml %s'
        #self.live_cmd = 'nmap -sP -oX %s/live_hosts'+self.pid+'.xml %s'
        #self.http_cmd = 'nmap -sT -sV --open  -p80,81,8000,8008,8080,8088,1433,3306,3389,21,22,23,110,25,443 -oX %s/http_hosts'+self.pid+'.xml %s'
        #self.http_cmd = 'nmap -sT -sV -n --open  -p80,81,8000,8008,8080,8088,8888,1433,3306,3389,21,22,23,110,25,443 -oX %s/http_hosts'+self.pid+'.xml %s'
        #2010-03-07 加-n参数，不进行DNS查询，速度提升至少10倍
        '''
        self.xmlpath = xmlpath
        self.live_xmlfile = xmlpath + '/live_hosts' + pid + '.xml'
        self.http_xmlfile = xmlpath + '/http_hosts' + pid + '.xml'
        self.pid = pid

        self.live_cmd = 'nmap -sP -n -oX %s -T%s %s' % (self.live_xmlfile, speed, ips)

        if ports:
            self.http_cmd = 'nmap -PN -sT -sV -n -T' + speed + ' --open  -p' + ports + ' -oX ' + self.http_xmlfile + ' %s'
        else:
            self.http_cmd = 'nmap -PN -sT -sV -n -T' + speed + ' --open  -p80,81,8000,8008,8080,8088,8888,443 -oX ' + self.http_xmlfile + ' %s'

    def get_live_hosts(self):
        '''获取存活IP列表
        '''
        self.up_hosts = []
        cmd = self.live_cmd
        os.popen(cmd)
        print(cmd)

        parser = Parser.Parser(self.live_xmlfile)
        session = parser.get_session()
        self.total_hosts = session.total_hosts
        self.up_hosts_num = session.up_hosts
        self.down_hosts_num = session.down_hosts

        for live_host in parser.all_hosts('up'):
            self.up_hosts.append(live_host.ip)

        return self.up_hosts

    def get_http_hosts(self, ips):
        '''返回IP检测结果：包含http服务的IP列表，每个IP对应的开放端口服务
        '''
        self.http_dict = {}
        self.host_dict = {}
        cmd = self.http_cmd % ips
        os.popen(cmd)
        print(cmd)

        parser = Parser.Parser(self.http_xmlfile)
        session = parser.get_session()

        for live_http in parser.all_hosts('up'):
            ip = live_http.ip
            http_ports = []
            services = []

            for port in live_http.get_ports('tcp', 'open'):
                s = live_http.get_service('tcp', port)

                if not s:
                    continue

                if s.name == 'http':
                    http_ports.append(port)

                if s.name == 'unknown' and 'Server:' in s.fingerprint:
                    http_ports.append(port)
                    s.name = 'http'
                # print s.name,port,ip,s.fingerprint

                services.append({
                    'port': port,
                    'name': s.name,
                    'product': s.product,
                    'version': s.version
                })

            if http_ports:
                self.http_dict[ip] = http_ports

            self.host_dict[ip] = services

        return self.http_dict, self.host_dict


def main(ips, pid='', ports=None, speed=None, prog=None, alive=True):
    '''接口函数
    '''
    xmlpath = os.path.join(config.LOG_PATH, 'nmap')
    n = Nmap(xmlpath, pid, ips, ports)

    if alive:
        liveList = n.get_live_hosts()
        if not liveList:
            return {}, {}
        if prog:
            prog.set_live_num(len(liveList))
        liveIps = ' '.join(liveList)
    else:
        liveList = parse_full_ip_list(ips)
        if prog:
            prog.set_live_num(len(liveList))
        liveIps = ' '.join(liveList)
    result = n.get_http_hosts(liveIps)

    if os.path.exists(xmlpath + '/live_hosts' + pid + '.xml'):
        os.unlink(xmlpath + '/live_hosts' + pid + '.xml')

    if os.path.exists(xmlpath + '/http_hosts' + pid + '.xml'):
        os.unlink(xmlpath + '/http_hosts' + pid + '.xml')

    return result


if __name__ == '__main__':
    from optparse import OptionParser

    usage = "python get_nmap_result.py -i 192.168.10.1-254"
    parser = OptionParser(usage)
    parser.add_option("-i", "--ip", dest="ip", default="",
                      help="ip range to be scaned, eg: 192.168.10.2 192.168.10.1-254 192.168.10.*")
    (options, args) = parser.parse_args()

    g_ips = options.ip

    from pprint import pprint

    pprint(main(g_ips))